package org.egedede.osgi.guishell.model;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;

import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import org.osgi.framework.Bundle;

public class BundleTreeModel implements TreeModel{

	private final Set<Bundle> bundles;
	private final EventListenerList events;

	public BundleTreeModel(Set<Bundle> bundles){
		this.bundles = bundles;
		this.events = new EventListenerList();
	}


	public void addTreeModelListener(TreeModelListener tml) {
		events.add(TreeModelListener.class, tml);
	}

	public Object getChild(Object parent, int index) {
		return bundles.toArray()[index];
	}

	public int getChildCount(Object parent) {
		return bundles.size();
	}

	public int getIndexOfChild(Object parent, Object child) {
		LinkedList<Bundle> tmp = new LinkedList<Bundle>();
		tmp.addAll(bundles);
		return tmp.indexOf(child);
	}

	public Object getRoot() {
		return bundles;
	}

	public boolean isLeaf(Object node) {
		return !node.equals(bundles);
	}

	public void removeTreeModelListener(TreeModelListener tml) {
		events.remove(TreeModelListener.class, tml);
	}

	public void valueForPathChanged(TreePath path, Object newValue) {
		TreeModelEvent tme = new TreeModelEvent(newValue, path);
		for(TreeModelListener listener : events.getListeners(TreeModelListener.class)){

			listener.treeStructureChanged(tme);
		}
	}

	public void updateBundles(Set<Bundle> newBundles){
		Collection<Bundle> existingBundles = new LinkedList<Bundle>();
		existingBundles.addAll(bundles);
		for(Bundle bundle : newBundles){
			if(bundles.contains(bundle)){
				existingBundles.remove(bundle);
			}else{
				bundles.add(bundle);
			}
		}
		bundles.removeAll(existingBundles);
		TreePath treePath = new TreePath(bundles);
		valueForPathChanged(treePath ,bundles);
	}

}
